package db

import (
	"errors"
	"time"

	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	_ "github.com/go-sql-driver/mysql"
	_ "github.com/lib/pq"
)

const (
	DB_ALIASNAME    = "db_aliasname"
	DB_DRIVERNAME   = "db_drivername"
	DB_URL          = "db_url"
	DB_MaxIdleConns = "db_MaxIdleConns"
	DB_MaxOpenConns = "db_MaxOpenConns"
)

var (
	AliasName    = "default"
	maxIdleConns = 5
	maxOpenConns = 9
)

func init() {

	drivername := beego.AppConfig.String(DB_DRIVERNAME)
	url := beego.AppConfig.String(DB_URL)

	if v, err := beego.AppConfig.Int(DB_MaxIdleConns); err == nil {
		maxIdleConns = v
	}
	if v, err := beego.AppConfig.Int(DB_MaxOpenConns); err == nil {
		maxOpenConns = v
	}

	if v := beego.AppConfig.String(DB_ALIASNAME); v != "" {
		AliasName = v
	}

	orm.RegisterDataBase(AliasName, drivername, url, maxIdleConns, maxOpenConns)
	orm.RegisterModel(new(NotifyInfo), new(AppInfo))
}

func ReBuildDb(drop, verbose bool) (err error) {
	// 数据库别名
	name := AliasName
	// drop table 后再建表
	force := drop
	// verbose 打印执行过程
	// 遇到错误立即返回
	err = orm.RunSyncdb(name, force, verbose)
	return err
}

type NotifyInfo struct {
	Id      int       `orm:"auto;pk;column(id)"`
	Appname string    `orm:"column(appname);size(255)"`
	Subject string    `orm:"column(subject);size(128)"`
	Content string    `orm:"column(content);type(text)"`
	Created time.Time `orm:"column(created);type(datetime);auto_now_add"`
}

func (this *NotifyInfo) TableName() string {
	return "notify_info"
}

func (this *NotifyInfo) TableIndex() [][]string {
	return [][]string{
		[]string{"Id", "Appname"},
	}
}

func (this *NotifyInfo) Save() (id int64, err error) {
	if this.Appname == "" {
		return 0, errors.New("Notify info Appname must be not empty.")
	} else {
		db := orm.NewOrm()
		id, err := db.Insert(this)
		if err != nil {
			return 0, errors.New("Save NotifyInfo failed.")
		} else {
			return id, nil
		}
	}
}

type AppInfo struct {
	Id      int       `orm:"colum(id);auto;pk"`
	Appname string    `orm:"column(appname);size(255);unique"`
	Mark    string    `orm:"column(mark);size(255);null"`
	Created time.Time `orm:"column(created);type(datetime);auto_now_add"`
}

func (this *AppInfo) TableName() string {
	return "app_info"
}

func (this *AppInfo) IsExistAppname() bool {
	db := orm.NewOrm()
	err := db.QueryTable(this.TableName()).Filter("appname").One(this)
	if err == orm.ErrMultiRows || err == orm.ErrNoRows {
		return false
	} else {
		return true
	}
}

func (this *AppInfo) Save() (id int64, err error) {
	if this.Appname == "" {
		return 0, errors.New("AppInfo filed appname must be not empty.")
	}
	if this.IsExistAppname() {
		return 0, errors.New("AppInfo appname=" + this.Appname + " record already exist .")
	} else {
		db := orm.NewOrm()
		id, err := db.Insert(this)
		if err != nil {
			return 0, errors.New("Save AppInfo failed.")
		} else {
			return id, nil
		}
	}
}
